package com.sz.service.frame;

import com.sz.bean.Page;
import com.sz.dao.frame.BaseDao;
import com.sz.exception.FindException;
import com.sz.exception.RemoveException;
import com.sz.exception.SaveException;
import com.sz.pojo.frame.BaseObject;
import com.sz.util.ToolStr;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class BaseService<T extends BaseObject<T>> {
    
    /** 上传文件路径 */
    public static final String UPLOADURL = "/file";

    @Autowired
    protected BaseDao<T> baseDao;

    private Class<T> type = null;

    
    public BaseService(Class<T> type) {
        this.type = type;
    }
    

    /**
     * 查询全部
     * 
     */
    public List<T> findAll() {
        StringBuffer hql = new StringBuffer("from ").append(type.getSimpleName());
        return baseDao.find4Params(hql.toString(), null);
    }
    
    /**
     * 使用语句查询
     * 
     * @param hql
     * @param params
     * @return
     */
    public List<Object[]> find(final String hql, final Map<String, Object> params){
        return baseDao.find4HQL(hql, params);
    }
    
    /**
     * 使用语句查询
     * 
     * @param hql
     * @param params
     * @param idStr：统计字段名，如果多表关联一定要写
     * @return
     */
    public Integer count(final String hql, final Map<String, Object> params, String idStr){
        return baseDao.countObject(hql, params, idStr);
    }
    
    /**
     * 使用语句查询
     * 
     * @param hql
     * @param params
     * @return
     */
    public Integer count(final String hql, final Map<String, Object> params){
        return baseDao.countObject(hql, params);
    }

    /**
     * 分页查询
     * 
     */
    public List<T> findAll4Page(Page page) {
        StringBuffer hql = new StringBuffer("from ").append(type.getSimpleName());
        return baseDao.find4Page(hql.toString(), null, page);
    }

    /**
     * 根据条件查询（分页）
     * @param page
     * @param paramsOld 查询参数 key：value
     * @return
     */
    public List<T> find4Page(Page page, Map<String , Object> paramsOld) {
        StringBuffer hql = new StringBuffer("from ").append(type.getSimpleName());
        Map<String , Object> params = new HashMap<String , Object>();
        hql.append(" where 1 = 1 ");
        if (paramsOld != null && paramsOld.size() > 0) {
            for (String keyOld : paramsOld.keySet()) {
                String str = keyOld.trim();
                String key = str.substring(0, str.indexOf(" ")).replace(".id", "Id");
                params.put(key, paramsOld.get(keyOld));
                hql.append(" AND ");
                hql.append(str);
                hql.append(" :");
                hql.append(key);
            }
        }
        return baseDao.find4Page(hql.toString(), params, page, "id");
    }

    /**
     * 根据条件查询（分页）
     * @param page
     * @param paramsOld
     * @param order-排序
     * @return
     */
    public List<T> find4Page(Page page, Map<String , Object> paramsOld, String order) {
        StringBuffer hql = new StringBuffer("from ").append(type.getSimpleName());
        Map<String , Object> params = new HashMap<String , Object>();
        hql.append(" where 1 = 1 ");
        if (paramsOld != null && paramsOld.size() > 0) {
            for (String keyOld : paramsOld.keySet()) {
                String str = keyOld.trim();
                String key = str.substring(0, str.indexOf(" ")).replace(".id", "Id");
                params.put(key, paramsOld.get(keyOld));
                hql.append(" AND ");
                hql.append(str);
                hql.append(" :");
                hql.append(key);
            }
        }
        hql.append(order);
        return baseDao.find4Page(hql.toString(), params, page, "id");
    }
    
    /**
     * 根据条件查询
     * @param paramsOld
     * @return
     */
    public List<T> find4Params(Map<String , Object> paramsOld) {
        StringBuffer hql = new StringBuffer("from ").append(type.getSimpleName());
        Map<String , Object> params = new HashMap<String , Object>();
        hql.append(" where 1 = 1 ");
        if (paramsOld != null && paramsOld.size() > 0) {
            for (String keyOld : paramsOld.keySet()) {
                String str = keyOld.trim();
                String key = str.substring(0, str.indexOf(" ")).replace(".id", "Id");
                params.put(key, paramsOld.get(keyOld));
                hql.append(" AND ");
                hql.append(str);
                hql.append(" :");
                hql.append(key);
            }
        }
        return baseDao.find4Params(hql.toString(), params);
    }
    
    /**
     * 根据条件查询
     * @param paramsOld
     * @return
     */
    public List<T> szFind4Params(Map<String , Object> paramsOld) {
        StringBuffer hql = new StringBuffer("from ").append(type.getSimpleName());
        Map<String , Object> params = new HashMap<String , Object>();
        hql.append(" where 1 = 1 ");
        if (paramsOld != null && paramsOld.size() > 0) {
            for (String keyOld : paramsOld.keySet()) {
                String str = keyOld.trim();
                String key = str.substring(0, str.indexOf(" ")).replace(".id", "Id");
                params.put(key, paramsOld.get(keyOld));
                hql.append(" AND ");
                hql.append(str);
                hql.append(" :");
                hql.append(key);
            }
        }
        return baseDao.find4Params(hql.toString(), params);
    }
    
    /**
     * 根据条件查询
     * @param paramsOld
     * @param order-排序
     * @return
     */
    public List<T> find4Params(Map<String , Object> paramsOld, String order) {
        StringBuffer hql = new StringBuffer("from ").append(type.getSimpleName());
        Map<String , Object> params = new HashMap<String , Object>();
        hql.append(" where 1 = 1 ");
        if (paramsOld != null && paramsOld.size() > 0) {
            for (String keyOld : paramsOld.keySet()) {
                String str = keyOld.trim();
                String key = str.substring(0, str.indexOf(" ")).replace(".id", "Id");
                params.put(key, paramsOld.get(keyOld));
                hql.append(" AND ");
                hql.append(str);
                hql.append(" :");
                hql.append(key);
            }
        }
        hql.append(order);
        return baseDao.find4Params(hql.toString(), params);
    }
    
    /**
     * 根据条件查询
     * @param params
     * @return
     */
    public T find4ParamsUnique(Map<String , Object> params) {
        List<T> tList = this.find4Params(params);
        if(tList != null && tList.size() > 0){
            return tList.get(0);
        }else{
            return null;
        }
    }
    
    /**
     * 根据条件查询
     * @param params
     * @param order-排序
     * @return
     */
    public T find4ParamsUnique(Map<String , Object> params, String order) {
        List<T> tList = this.find4Params(params, order);
        if(tList != null && tList.size() > 0){
            return tList.get(0);
        }else{
            return null;
        }
    }

    /**
     * 根据id查询（支持懒加载）
     * 
     * @param id
     * @return
     */
    public T load(Long id) {
        return this.load(id, false);
    }

    /**
     * 根据id查询（支持懒加载），如果throwException是true时，当查询结果为空或条件为空则报出异常
     * 
     * @param id
     * @param throwException
     * 
     * @param id
     * @return
     */
    public T load(Long id, boolean throwException) {
        if(true == throwException){
            if(id == null || id <= 0){
                throw new FindException("请传入正确的ID！");
            }
        }else{
            if(id == null || id <= 0){
                return null;
            }
        }
        T baseObject = baseDao.load(type, id);
        if(true == throwException){
            if(baseObject == null || baseObject.getId() == null || baseObject.getId() <= 0){
                throw new FindException("您查询的对象不存在。");
            }
        }
        return baseObject;
    }

    /**
     * 根据id查询
     * 
     * @param id
     * @return
     */
    public T get(Long id) {
        if(id == null || id <= 0){
            return null;
        }
        return baseDao.get(type, id);
    }

    /**
     * 根据id查询（支持懒加载），如果throwException是true时，当查询结果为空或条件为空则报出异常
     * 
     * @param id
     * @param throwException
     * 
     * @param id
     * @return
     */
    public T get(Long id, boolean throwException) {
        if(true == throwException){
            if(id == null || id <= 0){
                throw new FindException("请传入正确的ID！");
            }
        }else{
            if(id == null || id <= 0){
                return null;
            }
        }
        T baseObject = baseDao.get(type, id);
        if(true == throwException){
            if(baseObject == null || baseObject.getId() == null || baseObject.getId() <= 0){
                throw new FindException("您查询的对象不存在。");
            }
        }
        return baseObject;
    }

    /**
     * 添加或者更新表结构
     * 
     * @param t
     * @throws SaveException 
     */
    public void save(T t) {
        if(t == null){
            throw new SaveException("传参错误，请检查");
        }
        try {
            if(t.getId() == null || t.getId() <= 0){
                baseDao.save(t);
            }else{
                T vo = this.load(t.getId(), true);   
                vo.copy(t);
                baseDao.update(vo);
            }
        } catch (Exception e) {
            throw new SaveException(e.getMessage());
        }
    }

    /**
     * 删除
     * 
     * @param t
     */
    public void remove(T t) {
        if(t == null){
            throw new RemoveException("传参错误，请检查");
        }
        try {
            baseDao.remove(t);
        } catch (Exception e) {
            throw new RemoveException("删除失败，该模块正在被使用！");
        }
    }

    /**
     * 删除
     * 
     * @param ids 按当前拼成的ids删除对象
     */
    public void removeMultiple(String ids) {
      if(ids != null){
          T t = null;
          for (String didStr : ids.split(",")) {
              long id = ToolStr.sToL(didStr, 0L);
              t = this.get(id);
              if(t != null){
                  this.remove(t);
              }
          }
      }
    }

    /**
     * 删除
     * 
     * @param tList 将list中的所有对象删除
     */
    public void removeMultiple(List<T> tList) {
      for (T t : tList) {
          if(t != null){
              this.remove(t);
          }
      }
    }

    /**
     * 清空表
     */
    public void removeAll(){
        StringBuffer hql = new StringBuffer("delete from ").append(type.getSimpleName());
        baseDao.query(hql.toString(), null);
    }

}
